package com.aco.fatureapp.printer;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import android.os.SystemClock;
import android.util.Log;

import com.aco.fatureapp.model.printer.Billing;
import com.aco.fatureapp.model.printer.Historic;
import com.aco.fatureapp.model.printer.Products;

public class SaeePrinter {

	protected MobilePrinter mMobilePrint = null;
	public static boolean sLibStatus = false;
	public static boolean sConnected = false;
	public static boolean sKeepConnection = false;
	private String mPrinterName = null;
	public static final String MPT3 = "MPT-III";
	public static final String MAC = "00:02:5B:B3:B4:DB";

	public SaeePrinter(MobilePrinter mp) {
		if (mp == null) {
			this.mMobilePrint = new MobilePrinter();
		}
		else {
			this.mMobilePrint = mp;
		}
		sLibStatus = this.mMobilePrint.lnitLib();
	}

	public SaeePrinter() {
		this.mMobilePrint = new MobilePrinter();
		sLibStatus = this.mMobilePrint.lnitLib();
	}

	private int knownPrinter(ArrayList<String> strList) {
		int known = -1;

		for (int i = 0; i < strList.size(); i++) {
			if (i % 2 == 0) {
				if ((strList.get(i).equals("MPT-II"))
						|| (strList.get(i).equals("MPT-III"))
						|| (strList.get(i).equals("INPUTSERVICE"))) {
					if (strList.get(i + 1).substring(0, 8).equals("00:02:5B")) {
						known = i;
						return known;
					}
				}

			}

		}

		return known;
	}

	private boolean knownPrinter(String printerName, String macaddress) {
		boolean known = false;

		if ((printerName.equals("MPT-II")) || (printerName.equals("MPT-III"))
				|| (printerName.equals("INPUTSERVICE"))) {
			if (macaddress.substring(0, 8).equals("00:02:5B")) {
				return true;
			}

		}

		return known;
	}

	private int knownPrinter(ArrayList<String> strList, String printerName) {
		int known = -1;

		for (int i = 0; i < strList.size(); i++) {
			if (i % 2 == 0) {
				if (strList.get(i).equals(printerName)) {
					if (strList.get(i + 1).substring(0, 8).equals("00:02:5B")) {
						known = i;
						return known;
					}
				}

			}

		}

		return known;
	}

	public boolean connect(String printerName, String macaddress, boolean keepC) {
		if (knownPrinter(printerName, macaddress)) {
			ArrayList<String> strList = this.mMobilePrint.getBondedDevices();

			if (sLibStatus) {
				this.mMobilePrint.lnitLib();
			}
			if (!sKeepConnection) {
				strList = new ArrayList<String>();

				sConnected = !disconnect();

				this.mMobilePrint = new MobilePrinter();
				this.mMobilePrint.lnitLib();

				strList.add(0, printerName);
				strList.add(1, macaddress);

				if (this.mMobilePrint.connectDevice(strList, 0)) {
					sConnected = true;
					sKeepConnection = keepC;
					return true;
				}
			}
		}

		return false;
	}

	public boolean connect(boolean keepC) {
		if (sLibStatus) {
			this.mMobilePrint.lnitLib();
		}
		if (!sKeepConnection) {
			this.mMobilePrint = new MobilePrinter();
			this.mMobilePrint.lnitLib();
			ArrayList<String> strList = this.mMobilePrint.getBondedDevices();

			int printerMac = knownPrinter(strList);
			if ((printerMac != -1)
					&& (this.mMobilePrint.connectDevice(strList, printerMac))) {
				sConnected = true;
				sKeepConnection = keepC;
				return true;
			}

		}

		return false;
	}

	public boolean connect(String printerName, boolean keepC) {
		if (sLibStatus) {
			this.mMobilePrint.lnitLib();
		}
		if (!sKeepConnection) {
			this.mMobilePrint = new MobilePrinter();
			this.mMobilePrint.lnitLib();
			ArrayList<String> strList = this.mMobilePrint.getBondedDevices();

			int printerMac = knownPrinter(strList, printerName);
			if ((printerMac != -1)
					&& (this.mMobilePrint.connectDevice(strList, printerMac))) {
				sConnected = true;
				sKeepConnection = keepC;
				return true;
			}

		}

		return false;
	}

	public boolean disconnect() {
		if (sConnected) {
			this.mMobilePrint.closeConnect();
		}
		sKeepConnection = false;

		return true;
	}

	public String getPrinterName() {
		return this.mPrinterName;
	}

	public MobilePrinter getMobilePrinter() {
		return this.mMobilePrint;
	}

	public void imprimir(Billing billing) {

		try {
			// por linha cabem 46 letras na fonte normal.

			mMobilePrint.reset();

			// Buscar o black mark.
			mMobilePrint.goBlackMark();

			// Default 1mm(8dots)
			mMobilePrint.setLineSpace(36);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.sendDensity(6);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.setPositionAbsolute(5);
			// width, height, bold, underline, minifont
			mMobilePrint.formatString(false, true, true, false, false);
			mMobilePrint.sendString(getEspacoDir(billing.inscricao, 20));

			mMobilePrint.sendString(getEspacoDir(billing.localizacao, 14));

			mMobilePrint.sendString(billing.competencia);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.reset();
			mMobilePrint.setLineSpace(1);
			mMobilePrint.reset();
			mMobilePrint.formatString(false, false, false, false, false);

			//
			mMobilePrint.printAndLineFeed();

			mMobilePrint.printAndLineFeed();
			mMobilePrint.sendString(getEspacoDir(billing.nomeCliente, 46));
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.endereco, 46));
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.bairro, 46));
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.cidade + "-"
					+ billing.uf, 46));
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.leiturista, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.setPositionAbsolute(10);
			mMobilePrint.sendString(getEspacoDir(billing.classe, 12));

			mMobilePrint.sendString(billing.a_e);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.setPositionAbsolute(9);
			mMobilePrint.sendString(getEspacoDir(billing.tarifa, 14));

			mMobilePrint.sendString(billing.economias);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			Historic[] historics = billing.historics;

			// 1 linha do histórico de leitura.
			mMobilePrint.sendString(getEspacoEsq(billing.localizacao, 18));
			// 1 linha do histório
			printHistoric(historics, 1, 15);

			mMobilePrint.printAndLineFeed();

			// 2 linha do histório
			printHistoric(historics, 2, 33);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.hidrometro, 14));

			mMobilePrint.sendString(getEspacoEsq(billing.dataInstalacao, 10));

			// 3 linha do histório
			printHistoric(historics, 3, 9);
			mMobilePrint.printAndLineFeed();

			// 4 linha do histório
			printHistoric(historics, 4, 33);
			mMobilePrint.printAndLineFeed();

			// 5 linha do histório
			printHistoric(historics, 5, 33);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.dataLeitura, 14));

			mMobilePrint.sendString(getEspacoDir(billing.leituraAnterior, 5));
			// 6 linha do histório
			printHistoric(historics, 6, 14);

			mMobilePrint.printAndLineFeed();

			// 7 linha do histório
			printHistoric(historics, 7, 33);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.dataLeitura, 14));

			mMobilePrint.sendString(getEspacoDir(billing.leituraAtual, 4));
			// 8 linha do histório
			printHistoric(historics, 8, 14);
			mMobilePrint.printAndLineFeed();

			// 9 linha do histório
			printHistoric(historics, 9, 33);
			mMobilePrint.printAndLineFeed();

			mMobilePrint.sendString(getEspacoDir(billing.diasConsumo, 14));

			mMobilePrint.sendString(billing.consumo);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			// begin line
			mMobilePrint.setPositionAbsolute(8);
			mMobilePrint.sendString(getEspacoDir(billing.media, 23));
			mMobilePrint.sendString(getEspacoDir(billing.ocorrencia, 18));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();
			// end line

			mMobilePrint.sendString(getEspacoDir(billing.mensagem1, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.mensagem2, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.mensagem3, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.mensagem4, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			Products[] products = billing.products;

			for (int index = 1; index <= products.length; index++) {

				Products product = products[index - 1];

				mMobilePrint.sendString(getEspacoEsq(product.codigo, 5));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoDir(product.descricao, 22));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoEsq(product.parcela, 5));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoEsq(product.valor, 10));
				mMobilePrint.printAndLineFeed();
				mMobilePrint.reset();

				if (index == products.length) {
					mMobilePrint.setLineSpace(64);
					mMobilePrint.printAndLineFeed();
				}
			}

			// width, height, bold, underline, minifont
			// begin line
			mMobilePrint.formatString(false, true, true, false, false);
			mMobilePrint.setPositionAbsolute(18);
			mMobilePrint.sendString(getEspacoDir(billing.dataVencimento, 24));
			mMobilePrint.sendString(billing.totalConta);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();
			// end line

			mMobilePrint.setLineSpace(24);
			mMobilePrint.printAndLineFeed();

			// begin line
			mMobilePrint.formatString(false, false, false, false, false);
			mMobilePrint.setPositionAbsolute(7);
			mMobilePrint.sendString(getEspacoDir(billing.multa, 15));
			mMobilePrint.sendString(getEspacoDir(billing.valor, 18));
			mMobilePrint.sendString(getEspacoDir(billing.jurosDiarios, 8));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();
			// end line

			mMobilePrint.setLineSpace(1);
			mMobilePrint.reset();

			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.setPositionAbsolute(13);
			mMobilePrint.sendString(getEspacoDir(billing.reservatorio, 29));
			mMobilePrint.sendString(getEspacoDir(billing.dataColeta, 10));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.setPositionAbsolute(13);
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo1, 7));
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo2, 6));
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo3, 5));
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo4, 7));
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo5, 9));
			mMobilePrint.sendString(getEspacoDir(billing.reserCampo6, 3));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.mensagem5, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.mensagem5, 46));
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.printAndLineFeed();
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir("", 26));
			mMobilePrint.sendString(billing.inscricao);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir("", 28));
			mMobilePrint.sendString(billing.nomeCliente.substring(0, 20));
			mMobilePrint.printAndLineFeed();

			mMobilePrint.reset();
			mMobilePrint.setLineSpace(48);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			mMobilePrint.sendString(getEspacoDir(billing.inscricao, 14));
			mMobilePrint.sendString(getEspacoDir(billing.competencia, 11));
			mMobilePrint.sendString(getEspacoDir(billing.dataVencimento, 13));
			mMobilePrint.sendString(getEspacoDir(billing.totalConta, 10));

			mMobilePrint.printAndLineFeed();
			mMobilePrint.sendDensity(10);
			mMobilePrint.printAndLineFeed();
			mMobilePrint.sendString(billing.codigoBarrasComDigito);

			mMobilePrint.printAndLineFeed();
			mMobilePrint.reset();

			// mMobilePrint.rotate80Graus();
			mMobilePrint.printBarcode(MobilePrinter.BC_ITF, 2, 90, 0,
					billing.codigoBarras);

			//
			// byte[] bytes = Interleave2of5.modToByte(
			// "82660000000299600099000000002800100066731025").getBytes();
			//
			// mMobilePrint.printBarcode(70, 2, 90, 0, bytes);

			mMobilePrint.printAndLineFeed();

			mMobilePrint.reset();
			SystemClock.sleep(120);
		}
		catch (Exception ex) {
			Log.e("ERRO IMPRESSAO", ex.getMessage());
		}
	}

	private void printHistoric(Historic[] historics, int index,
			int tamPrimeiraColuna) throws UnsupportedEncodingException {
		Historic historic = historics[index - 1];
		mMobilePrint.sendString(getEspacoEsq(historic.competencia,
				tamPrimeiraColuna));
		mMobilePrint.sendString(getEspacoEsq(historic.consumo, 7));
		mMobilePrint.sendString(getEspacoEsq(historic.ocorrencia, 8));
	}

	/**
	 * Método que inclui espaços em uma string caso ela tenha menos caracteres
	 * que o especificado
	 */
	public static String getEspacoDir(String palavra,
			final Integer tamanhoMaximo) {
		if (palavra == null) {
			palavra = " ";
		}

		int tamanho = palavra.length();
		if (tamanho > tamanhoMaximo) {
			return palavra.substring(0, tamanhoMaximo);
		}

		if (tamanho < tamanhoMaximo) {
			for (int i = tamanho; i < tamanhoMaximo; i++) {
				// Adicionando espaço ao início da String
				palavra = palavra.concat(" ");
			}
		}
		return palavra;
	}

	public static String getEspacoEsq(String palavra,
			final Integer tamanhoMaximo) {
		if (palavra == null) {
			palavra = " ";
		}

		int tamanho = palavra.length();
		if (tamanho < tamanhoMaximo) {
			for (int i = tamanho; i < tamanhoMaximo; i++) {
				// Adicionando espaço ao início da String
				palavra = " ".concat(palavra);
			}
		}
		return palavra;
	}

}
